﻿using System;
using System.Diagnostics;
using Slippor.Douban.Radio.Assist;
using Slippor.Douban.Radio.Tracker;

namespace LocalTrackerData
{
    public class LocalTracker : ITracker
    {
        SongEntity _currentEntity;
        readonly SongTrackerHelper _songTrackerHelper = new SongTrackerHelper();

        public LocalTracker()
        {
            _songTrackerHelper.Initial();
        }

        #region ITracker Members
        private const String _key = "Local";
        public string Name
        {
            get { return _key; }
        }

        public void Track(Song song)
        {
            if (_currentEntity == null || song != _currentEntity.Song)
            {
                _currentEntity = TrackSong(song);
            }
        }

        public void TrackUpdate(ICommand command, Song song)
        {
            try
            {
                if (song != null)
                {
                    switch (command.Command)
                    {
                        case Command.Other:
                            TrackUpdateSong(song);
                            break;
                        case Command.Fav:
                            TrackUpdateSongFav(song);
                            break;
                        default:
                            TrackUpdateSongCommand(song, command.Command);
                            break;
                    }
                }
            }
            catch (Exception e)
            {
                Trace.TraceError(e.Message);
            }
        }

        public void Clear()
        {
            ;
        }

        public void Stop()
        {
            ;
        }
 
        public void Pause()
        {
        }

        public void Resume()
        {
        }
        #endregion

        private static object _forLock = new object();
        private SongEntity TrackSong(Song song)
        {
            long id = 0;
            lock (_forLock)
            {
                if (song.Album != null)
                {
                    int albumDate = 0;
                    if (song.Album.PublishDate != null && song.Album.PublishDate.Length >= 4)
                    {
                        Int32.TryParse(song.Album.PublishDate.Substring(0, 4), out albumDate);
                    }
                    id = _songTrackerHelper.Insert(song.SongID, song.Title, song.Album.AlbumID, song.Album.Name, song.Album.ArtistString, albumDate, song.ListenTime, song.FaveState == FavState.Fav, song.Album.Mark);
                }
                else
                {
                    id = _songTrackerHelper.Insert(String.Empty, song.Title, String.Empty, String.Empty, String.Empty, 0, song.ListenTime, song.FaveState == FavState.Fav, 0);
                }
                return new SongEntity(song) { ID = id };
            }
        }

        private void TrackUpdateSongCommand(Song song, Command command)
        {
            lock (_forLock)
            {
                long id = _songTrackerHelper.GetSong(song.Title, song.ListenTime);
                if (id > 0)
                {
                    _songTrackerHelper.UpdateCommandQuery(command, id);
                }
                else
                {
                    Track(song);
                }
            }
        }

        private void TrackUpdateSong(Song song)
        {
            lock (_forLock)
            {
                long id = _songTrackerHelper.GetSong(song.Title, song.ListenTime);
                if (id > 0)
                {
                    if (song.Album != null)
                    {
                        int albumDate = 0;
                        if (song.Album.PublishDate != null && song.Album.PublishDate.Length >= 4)
                        {
                            Int32.TryParse(song.Album.PublishDate.Substring(0, 4), out albumDate);
                        }
                        _songTrackerHelper.UpdateQuery(song.SongID, song.Album.AlbumID, song.Album.Name, song.Album.ArtistString, albumDate, song.FaveState == FavState.Fav, (decimal)song.Album.Mark, id);
                    }
                }
                else
                {
                    Track(song);
                }
            }
        }

        private void TrackUpdateSongFav(Song song)
        {
            lock (_forLock)
            {
                long id = _songTrackerHelper.GetSong(song.Title, song.ListenTime);
                if (id > 0)
                {
                    _songTrackerHelper.UpdateFavQuery(song.FaveState == FavState.Fav, id);
                }
                else
                {
                    Track(song);
                }
            }
        }
    }
}
